home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / tex / files / !tex / TeXsource / web2ctex / ctex / c / extra next >
Encoding:
Text File  |  1990-07-27  |  23.4 KB  |  954 lines

  1. /*
  2. There are a couple of fread & fwrite's in h.tex which I'll leave for now.
  3. (search for 'pending:' in the sources)
  4.  
  5. itex, extra: changed many fprintf's to os_fputs.  Still some complex
  6.              ones to do (eg with %d in them). Also a couple of fputc's
  7.              in the pool reading stuff.
  8.  
  9. tex0:
  10.   fprintf( stdout ,... only one occurance - changed to Fputs.
  11.  
  12. tex8:
  13.   fprintf( stdout ,...  all recoded as Fputs
  14.   fprintf( logfile ,... left as is - but may change one day if logfile
  15.                         goes into a window too...
  16.  
  17. */
  18.  
  19. /*
  20.  * Hand-coded routines for C TeX.
  21.  * This module should contain any system-dependent code.
  22.  *
  23.  * This code was written by Tim Morgan, drawing from other Unix
  24.  * ports of TeX.
  25.  */
  26.  
  27. #ifdef RISC_OS
  28. int multi_tasking_counter;
  29. extern int update_pending;
  30.  
  31. #define POLL()    \
  32.   do                                                                          \
  33.     {                                                                         \
  34.       if ((multi_tasking_counter = (multi_tasking_counter + 1) % 12) == 0  \
  35.           && text_poll (0) > 0)                                               \
  36.         text_update ();                                                       \
  37.     } while(0)
  38.  
  39. #endif
  40.  
  41. #ifdef ARTHUR
  42. #define NEXTSEP ','
  43. /* NEXTSEP is the character between file-names in an environment string. */
  44. #define PATHSEP '.'
  45. /* PATHSEP is the character between nodes in a hierarchical filing system. */
  46. #define Absolute(tex_name) (0 != 0) /* Too complex to work out properly!   */
  47.                                     /* So we cheat by having an empty item */
  48.                                     /* as the first item in a path         */
  49. #else
  50. #define NEXTSEP ':'
  51. #define PATHSEP '/'
  52. #define Absolute(tex_name) (*tex_name == '/')
  53. #endif
  54.  
  55. #define CATCHINT                 /* Catch ^C's */
  56.  
  57. #define EXTERN                  /* Actually instantiate globals here */
  58. #include "texd.h"
  59.  
  60. /* Various include files we'll need */
  61. #ifdef  CATCHINT
  62. #include <signal.h>
  63. #endif
  64. #ifdef  BSD
  65. #include <sys/time.h>
  66. #include <sys/wait.h>
  67. #else
  68. #include <time.h>
  69. #endif
  70. #if defined(BSD)||defined(SYSV)
  71. #include <sgtty.h>
  72. #endif
  73.  
  74. static char *texeditvalue = EDITOR;
  75.  
  76. #ifdef  SYSV
  77. #define index   strchr          /* Sys V compatibility */
  78. extern int *sprintf();
  79. #else
  80. #ifndef ARTHUR /* Should be in stdio.h */
  81. extern char *sprintf();
  82. #endif
  83. #endif
  84.  
  85. #ifdef ARTHUR       /*ACORN - actually, should be #ifdef __STDC__*/
  86. #define index strchr
  87. #endif
  88.  
  89. /* C library stuff that we're going to use */
  90. extern char *strcpy(), *strcat(), *malloc(), *index(), *getenv();
  91.  
  92. /* Local stuff */
  93. static int gargc;
  94. static char **gargv;
  95. static char texformats[filenamesize], texinputs[filenamesize];
  96. static char texfonts[filenamesize], texpool[filenamesize];
  97. static char my_realnameoffile[filenamesize];
  98.  
  99.  
  100. #ifdef RISC_OS_NEVER
  101.   /**************** Yes - but who sets it up??? And it seems a bit weird? */
  102. #ifdef  CATCHINT
  103. /* If we're catching ^C, come here when one comes in. */
  104. static catchint()
  105. {
  106.     interrupt = 1;
  107.     (void) signal(SIGINT, catchint);
  108. }
  109. #endif
  110. #endif
  111.  
  112. /* Do the obvious */
  113. get_date_and_time(minutes, day, month, year)
  114. integer *minutes, *day, *month, *year;
  115. {
  116.     time_t clock;
  117.     struct tm *tmptr;
  118.  
  119.     clock = time(0);
  120.     tmptr = localtime(&clock);
  121.  
  122.     *minutes = tmptr->tm_hour * 60 + tmptr->tm_min;
  123.     *day = tmptr->tm_mday;
  124.     *month = tmptr->tm_mon + 1;
  125.     *year = tmptr->tm_year + 1900;
  126. #ifdef RISC_OS_NEVER
  127.   /**************** WHAT THE HELL??? Why do this *here* ????*/
  128.   /* (its not what *I* call obvious.... :-) ) */
  129. #ifdef  CATCHINT
  130.     (void) signal(SIGINT, catchint);
  131. #endif
  132. #endif
  133. }
  134.  
  135. #ifdef  INITEX
  136. /* Same as in Pascal --- return TRUE if EOF or next char is newline */
  137. eoln(f)
  138. FILE *f;
  139. {
  140.     register int c;
  141.  
  142. #ifdef RISC_OS
  143.     if (os_feof(f)) return(true);
  144.     c = os_getc(f);
  145.     if (c != EOF)
  146.         (void) os_ungetc(c, f);
  147. #else
  148.     if (feof(f)) return(true);
  149.     c = getc(f);
  150.     if (c != EOF)
  151.         (void) ungetc(c, f);
  152. #endif
  153.     return (c == '\n' || c == EOF);
  154. }
  155. #endif  /* INITEX */
  156.  
  157. static void copy_path(ptr, defptr, override)
  158. char *ptr, *defptr, *override;
  159. {
  160.     if (override) {
  161.         if (strlen(override) >= 1024) {
  162. #ifdef RISC_OS
  163.             (void) os_fputs("Path too long", stderr);
  164.             uexit(1);
  165. #else
  166.             (void) fprintf(stderr, "Path too long\n");
  167.             exit(1);
  168. #endif
  169.         }
  170.         (void) strcpy(ptr, override);
  171.     }
  172.     else
  173.         (void) strcpy(ptr, defptr);
  174. }
  175.  
  176.  
  177. /* Initialize path variables for loading fonts and things */
  178. setpaths()
  179. {
  180.     copy_path(texformats, TEXFORMATS, getenv("TEXFORMATS"));
  181.     copy_path(texinputs, TEXINPUTS, getenv("TEXINPUTS"));
  182.     copy_path(texfonts, TEXFONTS, getenv("TEXFONTS"));
  183.     copy_path(texpool, TEXPOOL, getenv("TEXPOOL"));
  184. }
  185.  
  186. /*
  187.  *  The following procedure is due to sjc@s1-c.
  188.  *
  189.  *      calledit(filename, fnstart, fnlength, linenumber)
  190.  *
  191.  *  TeX82 can call this to implement the 'e' feature in error-recovery
  192.  *  mode, invoking a text editor on the erroneous source file.
  193.  *  
  194.  *  You should pass to "filename" the first character of the packed array
  195.  *  containing the filename, and to "fnstart" and "fnlength" the index and
  196.  *  length of the filename as it appears inside that array.
  197.  *  
  198.  *  Ordinarily, this invokes "/usr/ucb/vi". If you want a different
  199.  *  editor, create a shell environment variable TEXEDIT containing
  200.  *  the string that invokes that editor, with "%s" indicating where
  201.  *  the filename goes and "%d" indicating where the decimal
  202.  *  linenumber (if any) goes. For example, a TEXEDIT string for a
  203.  *  variant copy of "vi" might be:
  204.  *  
  205.  *      setenv TEXEDIT "/usr/local/bin/vi +%d %s"
  206.  *  
  207.  */
  208.  
  209. calledit(filename, fnstart, fnlength, linenumber)
  210. ASCIIcode filename[];
  211. poolpointer fnstart;
  212. integer fnlength, linenumber;
  213. {
  214.     char *temp, *command, c;
  215.     int sdone, ddone, i;
  216.  
  217.     sdone = ddone = 0;
  218.     filename += fnstart;
  219.  
  220.     /* Replace default with environment variable if possible.
  221.      * We can get away with a simple assignment because we don't call
  222.      * getenv() again.
  223.      */
  224.     if (NULL != (temp = getenv("TEXEDIT")))
  225.         texeditvalue = temp;
  226.  
  227.     /* Make command string containing envvalue, filename, and linenumber */
  228.     if (NULL ==
  229.         (command = (char *) malloc((unsigned) (strlen(texeditvalue) + fnlength
  230.                                    + 25)))) {
  231. #ifdef RISC_OS
  232.         (void)os_fputs("! Not enough memory to issue editor command", stderr);
  233.         uexit(1);
  234. #else
  235.         (void)fprintf(stderr, "! Not enough memory to issue editor command\n");
  236.         exit(1);
  237. #endif
  238.     }
  239.     temp = command;
  240.     while ((c = *texeditvalue++) != '\0') {
  241.         if (c == '%') {
  242.             switch (c = *texeditvalue++) {
  243.             case 'd':
  244.                 if (ddone) {
  245. #ifdef RISC_OS
  246.                     (void) os_fputs(
  247.                     "! Line number cannot appear twice in editor command",
  248.                     stderr);
  249.                     uexit(1);
  250. #else
  251.                     (void) fprintf(stderr,
  252.                     "! Line number cannot appear twice in editor command\n");
  253.                     exit(1);
  254. #endif
  255.                 }
  256.                 (void) sprintf(temp, "%d", linenumber);
  257.                 while (*temp != '\0')
  258.                     temp++;
  259.                 ddone = 1;
  260.                 break;
  261.             case 's':
  262.                 if (sdone) {
  263. #ifdef RISC_OS
  264.                     (void) os_fputs(
  265.                       "! Filename cannot appear twice in editor command",
  266.                       stderr);
  267.                     uexit(1);
  268. #else
  269.                     (void) fprintf(stderr,
  270.                       "! Filename cannot appear twice in editor command\n");
  271.                     exit(1);
  272. #endif
  273.                 }
  274.                 i = 0;
  275.                 while (i < fnlength)
  276.                     *temp++ = filename[i++];
  277.                 sdone = 1;
  278.                 break;
  279.             case '\0':
  280.                 *temp++ = '%';
  281.                 texeditvalue--; /* Back up to \0 to force termination. */
  282.                 break;
  283.             default:
  284.                 *temp++ = '%';
  285.                 *temp++ = c;
  286.                 break;
  287.             }
  288.         }
  289.         else
  290.             *temp++ = c;
  291.     }
  292.     *temp = '\0';
  293.  
  294.     /* Execute command. */
  295. #ifdef RISC_OS
  296.  /* Won't work, because needs wimp tasking */
  297. /*
  298.     if (system(command))
  299.         (void) fprintf(stderr, "! Trouble executing command %s\n", command);
  300.  */
  301.  
  302.     /* Quit, indicating TeX found an error */
  303.     uexit(1);
  304. #else
  305.     if (system(command))
  306.         (void) fprintf(stderr, "! Trouble executing command %s\n", command);
  307.  
  308.     /* Quit, indicating TeX found an error */
  309.     exit(1);
  310. #endif
  311. }
  312.  
  313.  
  314. /*
  315.  * Change a Pascal-like filename into a C-like string.
  316.  * If running on a non-ASCII system, will have to use xchr[]
  317.  * array to convert from internal character set (in the "nameoffile"
  318.  * array) into the enternal character set (in "realnameoffile").
  319.  * "nameoffile" in TeX is indexed starting at 1, but by the time
  320.  * we're called, it has already been bumped up by one.
  321.  */
  322. static packrealnameoffile(prefix, nameoffile)
  323. char *prefix, *nameoffile;
  324. {
  325.     register char *cp, *p, *q;
  326.  
  327.     p = prefix;
  328. /*    for (q = my_realnameoffile; p && *p && *p != ':'; *q++ = *p++);*/
  329.     for (q = my_realnameoffile; p && *p && *p != NEXTSEP; *q++ = *p++);
  330. #ifndef ARTHUR  /* Arthur pathnames include seperator */
  331.     if (prefix && *prefix)
  332.         *q++ = PATHSEP;
  333. #endif
  334.     for (cp = nameoffile, p = realnameoffile + 1; *cp != ' ' && *cp;)
  335. #ifdef  NONASCII
  336.         *q++ = xchr[*p++ = *cp++];
  337. #else
  338.         *q++ = (*p++ = *cp++);
  339. #endif
  340.     *p = ' ';
  341.     *q = '\0';
  342. }
  343.  
  344. #ifdef  BSD
  345. /*
  346.  * This code is from Chris Torek:
  347.  *
  348.  * The following is an internal-use-only routine that makes a core
  349.  * dump without any sort of error status.  It is used only when
  350.  * making a production TeX from a virtex, and is triggered by a magic
  351.  * file name requested as \input.
  352.  *
  353.  * This is what is known in computing circles as a hack.
  354.  */
  355. static void funny_core_dump()
  356. {
  357.         int pid, w;
  358.         union wait status;
  359.  
  360.         switch (pid = vfork()) {
  361.  
  362.         case -1:                /* failed */
  363.                 perror("vfork");
  364.                 exit(-1);
  365.                 /*NOTREACHED*/
  366.  
  367.         case 0:                 /* child */
  368.                 (void) signal(SIGQUIT, SIG_DFL);
  369.                 (void) kill(getpid(), SIGQUIT);
  370.                 (void) write(2, "how did we get here?\n", 21);
  371.                 _exit(1);
  372.                 /*NOTREACHED*/
  373.  
  374.         default:                /* parent */
  375.                 while ((w = wait(&status)) != pid && w != -1)
  376.                         ;
  377.                 if (status.w_coredump)
  378.                         exit(0);
  379.                 (void) write(2, "attempt to dump core failed\n", 28);
  380.                 exit(1);
  381.         }
  382. }
  383. #endif /* BSD */
  384.  
  385. /* Open an input file f */
  386. Openin(f, pathspec)
  387. FILE **f;
  388. int pathspec;
  389. {
  390.     register char *prefix, *nprefix;
  391.     register char *cp, *tex_name;
  392.  
  393. #ifdef  BSD
  394.     if (pathspec == inputpathspec &&
  395.         strncmp(nameoffile+1, "HackyInputFileNameForCoreDump.tex", 33) == 0)
  396.         funny_core_dump();
  397. #endif  /* BSD */
  398.     for (tex_name = &nameoffile[1]; *tex_name == ' '; ++tex_name);
  399.  
  400.     switch (pathspec) {
  401.     case inputpathspec:
  402.     case readpathspec:
  403.         prefix = texinputs;
  404.         break;
  405.     case fontpathspec:
  406.         prefix = texfonts;
  407.         break;
  408.     case poolpathspec:
  409.         prefix = texpool;
  410.         break;
  411.     case fmtpathspec:
  412.         prefix = texformats;
  413.         break;
  414.     default:                    /* "Can't" happen */
  415. #ifdef RISC_OS
  416.         (void) os_fputs("INTERNAL CONFUSION---IMPLEMENTATION ERROR", stderr);
  417.         uexit(1);
  418. #else
  419.         (void) fprintf(stderr, "INTERNAL CONFUSION---IMPLEMENTATION ERROR\n");
  420.         exit(1);
  421. #endif
  422.     }
  423. /*    if (*tex_name == '/') {*/ /* Absolute pathname-don't do path searching */
  424.     if Absolute(tex_name) {     /* Absolute pathname-don't do path searching */
  425.         for (cp = tex_name; *cp && *cp != ' '; ++cp);
  426.         *cp = '\0';
  427.         if (*f = fopen(tex_name, "r")) {
  428.             (void) strcpy(realnameoffile + 1, tex_name);
  429.             (void) strcat(realnameoffile + 1, " ");
  430.             if (pathspec == fontpathspec)
  431. #ifdef RISC_OS
  432.                 tfmtemp = os_getc(*f);  /* Simulate readahead on TFM files */
  433. #else
  434.                 tfmtemp = getc(*f);     /* Simulate readahead on TFM files */
  435. #endif
  436.             return (1);
  437.         }
  438.         return (0);
  439.     }
  440.     /* Else relative pathname */
  441.     while (prefix) {
  442.         packrealnameoffile(prefix, tex_name);
  443.         *f = fopen(my_realnameoffile, "r");
  444.         if (*f) {
  445.             (void) strcpy(realnameoffile + 1, my_realnameoffile);
  446.             (void) strcat(realnameoffile + 1, " ");
  447.             if (pathspec == fontpathspec)
  448. #ifdef RISC_OS
  449.                 tfmtemp = os_getc(*f);     /* Simulate Pascal readahead */
  450. #else
  451.                 tfmtemp = getc(*f);     /* Simulate Pascal readahead */
  452. #endif
  453.             return (1);
  454.         }
  455.         nprefix = index(prefix, NEXTSEP);
  456.         if (nprefix)
  457.             prefix = nprefix + 1;
  458.         else
  459.             break;
  460.     }
  461.     return (0);
  462. }
  463.  
  464. /* Open an output file f */
  465. Openout(f)
  466. FILE **f;
  467. {
  468.     register char *tex_name;
  469.  
  470.     for (tex_name = &nameoffile[1]; *tex_name == ' '; ++tex_name);
  471.     packrealnameoffile((char *) NULL, tex_name);
  472.     *f = fopen(my_realnameoffile, "w");
  473.     return (*f != NULL);
  474. }
  475.  
  476.  
  477. /*
  478.  * Read a line of input as efficiently as possible while still
  479.  * looking like Pascal.
  480.  * Sets last==first and returns FALSE if eof is hit.
  481.  * Otherwise, TRUE is returned and either last==first or buffer[last-1]!=' ';
  482.  * that is, last == first + length(line except trailing whitespace).
  483.  */
  484. boolean zinputln(f)
  485. FILE *f;
  486. {
  487.     register int i;
  488.  
  489.     last = first;
  490. #ifdef RISC_OS
  491.     while ( last < bufsize && ((i = os_getc(f)) != EOF) && i != '\n') {
  492. #else
  493.     while ( last < bufsize && ((i = getc(f)) != EOF) && i != '\n') {
  494. #endif
  495. #ifdef  NONASCII
  496.         buffer[last++] = i;
  497. #else
  498.         buffer[last++] = (i > 127 || i < 0)?' ':i;
  499. #endif
  500.     }
  501.     if (i == EOF && last == first)
  502.         return(false);
  503.     if (i != EOF && i != '\n') {
  504.         /* We didn't get whole line because of lack of buffer space */
  505. #ifdef RISC_OS
  506. /* PENDING: DO THIS BY HAND */
  507. /*
  508.         (void)fprintf(stderr, "\nUnable to read an entire line---bufsize=%d\n",
  509.                       bufsize);
  510.  */
  511.         uexit(1);
  512. #else
  513.         (void) fprintf(stderr, "\nUnable to read an entire line---bufsize=%d\n",
  514.             bufsize);
  515.         exit(1);
  516. #endif
  517.     }
  518.     buffer[last] = ' ';
  519.     if (last >= maxbufstack)
  520.         maxbufstack = last;     /* Record keeping */
  521.     /* Trim trailing whitespace by decrementing "last" */
  522.     while (last > first && (buffer[last-1] == ' ' || buffer[last-1] == '\t'))
  523.         --last;
  524.     /* Now, either last==first or buffer[last-1] != ' ' (or tab) */
  525. /*
  526.  * If we're running on a system with ASCII characters like TeX's
  527.  * internal character set, we can save some time by not executing
  528.  * this loop.
  529.  */
  530. #ifdef  NONASCII  /* BUG: Was *NOT*ASCII ! */
  531.     for (i = first; i <= last; i++)
  532.         buffer[i] = xord[buffer[i]];
  533. #endif
  534.     return(true);
  535. }
  536.  
  537. /*
  538.  * Clear any pending terminal input.
  539.  * The usual way to do this in Unix is to switch the terminal to get
  540.  * the current tty flags, set RAW mode, then switch back to the original
  541.  * setting.  If the user isn't in COOKED mode, though, this won't work.
  542.  * At least, it leaves his terminal in its original mode.
  543.  */
  544. #ifdef RISC_OS
  545. void text_update(void);  /* Used before header file pulled in... :-( */
  546. #endif
  547. clearterminal()
  548. {
  549. #ifdef  BSD
  550.     struct sgttyb sb;
  551.     int flags;          /* We save the original flags here */
  552.  
  553.     if (ioctl(fileno(stdout), TIOCGETP, &sb) < 0)
  554.         return;         /* Failed for some reason */
  555.     flags = sb.sg_flags;
  556.  
  557.     sb.sg_flags |= RAW;
  558.     if (ioctl(fileno(stdout), TIOCSETP, &sb) < 0)
  559.         return;         /* Punt if it fails */
  560.  
  561.     sb.sg_flags = flags;
  562.     (void) ioctl(fileno(stdout), TIOCSETP, &sb);
  563. #endif  /* BSD */
  564. #ifdef RISC_OS
  565. #if 0
  566.     if (text_poll(0) >= 0) text_update();
  567. #else
  568.     POLL ();
  569. #endif
  570.     /* Would be a little neater if this called wflush() - should
  571.        tidy up w* procs so that they don't take FILE * parameters.
  572.        On the other hand, this would preclude ever having multiple
  573.        windows (eg for the logfile) */
  574. #endif
  575. }
  576.  
  577.  
  578. /*
  579.  * Cancel any output cancellation (^O) by the user.  This is 4.2BSD code.
  580.  * Systems which don't have this feature might want to #define wakeupterminal
  581.  * to do nothing, rather than call this empty routine, but it's only called
  582.  * when about to read from the terminal, so the extra time (compared with
  583.  * the human's response time) is minimal.
  584.  */
  585. wakeupterminal()
  586. {
  587. #ifdef  BSD
  588.     int i = LFLUSHO;
  589.  
  590.     (void) ioctl(fileno(stdout), TIOCLBIC, (struct sgttyb *) &i);
  591. #endif  /* BSD */
  592. #ifdef RISC_OS
  593.   /* PENDING: **************** If window not open, do it now!!!!! */
  594. #if 0
  595.     if (text_poll(0) >= 0) text_update();
  596. #else
  597.     POLL ();
  598. #endif
  599. #endif
  600. }
  601.  
  602.  
  603. /*
  604.  * "Open the terminal for input".  Actually, copy any command-line
  605.  * arguments for processing.  If nothing is available, or we've
  606.  * been called already (and hence, gargc==0), we return with last==first.
  607.  */
  608. topenin()
  609. {
  610.     register int i;
  611.  
  612.     if (gargc > 1) {
  613.         buffer[first] = '\0';   /* This makes the first strcat work */
  614.         for (i=1; i<gargc; i++) {
  615.             (void) strcat((char *) &buffer[first], gargv[i]);
  616.             (void) strcat((char *) &buffer[first], " ");
  617.         }
  618.         gargc = 0;      /* Don't do this again */
  619.         for (last=first; buffer[last]; ++last);
  620.         for (--last; last >= first && buffer[last] == ' '; --last);
  621.         ++last;
  622.     }
  623.     else last = first;  /* This signals that nothing is available */
  624. }
  625.  
  626.  
  627. #ifdef  sequent
  628. /*
  629.  * On a Sequent Balance system under Dynix 2.1, if u and v are unsigned
  630.  * shorts or chars, then "(int) u - (int) v" does not perform a signed
  631.  * subtraction.  Hence we have to call this routine to force the compiler
  632.  * to treat u and v as ints instead of unsigned ints.  Sequent knows about
  633.  * the problem, but they don't seem to be in a hurry to fix it.
  634.  */
  635. integer ztoint(x)
  636. {
  637.     return(x);
  638. }
  639. #endif
  640.  
  641. /*
  642.  * Get things going under Unix: set up for rescanning the command line,
  643.  * then call TeX's main body.
  644.  */
  645.  
  646.  
  647. #ifdef RISC_OS
  648. #include "text.h"
  649. /* This section interfaces to the acorn Wimp - it could easily be interfaced
  650.    to any other character-based wimp system, say via curses? */
  651.  
  652. #define NUM_ROWS 29
  653. #define NUM_COLS 77
  654. int max_row = NUM_ROWS;
  655. int max_col = NUM_COLS;
  656. int s_row = 0;
  657. int s_col = 0;
  658. #endif
  659.  
  660.  
  661. main(argc, argv)
  662. int argc;
  663. char *argv[];
  664. {
  665.     gargc=argc;
  666.     gargv=argv;
  667. #ifdef RISC_OS
  668.     s_row = 0; s_col = 0;
  669.     if (text_init (max_col, max_row, max_row, "TeX", max_col, max_row, 27) == -1)
  670.       exit (1);
  671.     text_cursor(2, 42);
  672. #endif
  673.     texbody();
  674. #ifdef RISC_OS
  675.     /* PENDING: THIS IS PROBABLY A BUG.  I expect TeX exits via exit()
  676.        so will never get here.  If this is true, set up an exit handler
  677.        to close down the wimp */
  678.     /* In the meantime, I've redeclared uexit(n) to do a text_closedown */
  679.     text_closedown();
  680. #endif
  681.  
  682.  
  683. #ifdef  DEBUG
  684. getint()
  685. {
  686.     int i;
  687.  
  688.     if (fscanf(stdin, "%d", &i)) return(i);
  689.     return(0);
  690. }
  691. #endif  /* DEBUG */
  692.  
  693. #ifdef ARTHUR
  694. /* Since this is used in the dumping/undumping code, going to a file,
  695.    I can safely avoid routing it via the wimp indirections */
  696. void putw(int w, FILE *f) {
  697.   fputc(w & 255, f); w >>= 8;
  698.   fputc(w & 255, f); w >>= 8;
  699.   fputc(w & 255, f); w >>= 8;
  700.   fputc(w & 255, f);
  701. }
  702.  
  703. int getw(FILE *f) {
  704. int w;
  705.   w =     fgetc(f);
  706.   w = w | (fgetc(f)<<8);
  707.   w = w | (fgetc(f)<<16);
  708.   w = w | (fgetc(f)<<24);
  709.   return(w);
  710. }
  711. #ifdef RISC_OS      /* Running in RISC_OS Windows environment? */
  712.  
  713. /**************************************************************************/
  714.  
  715. int wfputc(char c, FILE *f) {
  716.   switch (c) {
  717.    case 8:
  718.       if (s_col > 0) s_col--;
  719.       text_cursor_pos(s_col, s_row);
  720.       break;
  721.    case 7:
  722.       art_vdu(7);
  723.       break;
  724.    case '\n':
  725.       if (s_row == max_row - 1) text_scroll ();
  726.       else s_row++;
  727.       s_col = 0;
  728.       text_cursor_pos(s_col, s_row);
  729. #if 0
  730.       if (text_poll(0) >= 0) text_update();
  731. #else
  732.       POLL ();
  733. #endif
  734.       break;
  735.    case 13:
  736.       s_col = 0;
  737.       text_cursor_pos(s_col, s_row);
  738. #if 0
  739.       if (text_poll(0) >= 0) text_update();
  740. #else
  741.       POLL ();
  742. #endif
  743.       break;
  744.    default:
  745.       if (c < 32) c = '?'; /* %should% report an error, but how? */
  746.       (void)text_putch(c, 0, s_col, s_row);
  747.       s_col = (s_col+1) % max_col;
  748.       if (!s_col) {
  749.         s_row = (s_row+1) % max_row;
  750.         if (s_row == 0) s_row = max_row - 1, text_scroll ();
  751.       }
  752.       text_cursor_pos(s_col, s_row);
  753.       break;
  754.    }
  755. }
  756.  
  757. static int os_ch = -1;
  758. int wgetc(FILE *f) {
  759. int i;
  760.   if (os_ch != -1) {
  761.     i = os_ch; os_ch = -1;
  762.     return(i);
  763.   }
  764.   while ( (i = text_inkey()) == -1 ) {
  765.     if (i = text_poll(1) >= 0) {
  766.       text_update();
  767.     } else break;
  768.     /* Detect 'close_window' by using text_poll(1)
  769.        and looking at result for -1 */
  770.   }
  771.   if (i == 13) i = '\n';
  772.   if ((i == -1)
  773.    || (i == ('c'&31))
  774.    || (i == 27)) {
  775.     raise(SIGINT);
  776.   } else {
  777.     if ((i == ('d'&31))
  778.      || (i == ('z'&31))) {
  779.       i = -1;
  780.     } else {
  781.       wfputc(i, stderr);
  782.     }
  783.   }
  784.   return (i);
  785. }
  786.  
  787. int wungetc(int c, FILE *f) {
  788.   os_ch = c;
  789. }
  790.  
  791. int wfputs(char *s, FILE *f) {
  792.   while (*s != '\0') {
  793.     (void) wfputc(*s, f);
  794.     s++;
  795.   }
  796.   (void) wfputc('\n', f);
  797. #if 0
  798.   text_poll(0); /* Multitask a bit more... */
  799. #else
  800.   POLL ();
  801. #endif
  802. }
  803.  
  804. int wfput(char *s, FILE *f) {
  805.   while (*s != '\0') {
  806.     (void) wfputc(*s, f);
  807.     s++;
  808.   }
  809. #if 0
  810.   text_poll(0); /* Multitask a bit more... */
  811. #else
  812.   POLL ();
  813. #endif
  814. }
  815.  
  816. void wfflush(FILE *f) {
  817. #if 0
  818.   if (text_poll(0) >= 0) text_update();
  819. #else
  820.   POLL ();
  821. #endif
  822. }
  823.  
  824. int wfeof(FILE *f) {
  825.   /* Return if escape pressed OR close icon pressed.
  826.      remember that esc should be asynch - so set a flag
  827.      (don't raise a signal as in other progs - TeX doesn't like them */
  828. #if 0
  829.   if (text_poll(0) >= 0) text_update();
  830. #else
  831.   POLL ();
  832. #endif
  833.   return(false);
  834. }
  835.  
  836. int wfclose(FILE *f) {
  837. #if 0
  838.   if (text_poll(0) >= 0) text_update();
  839. #else
  840.   POLL ();
  841. #endif
  842. }
  843. /**************************************************************************/
  844.  
  845. void os_readln(FILE *f) {
  846.   if (f == stdin) {
  847.     int c;
  848.     while ((c=wgetc(f))!='\n' && c!=EOF); 
  849.   } else {
  850.     int c;
  851.     while ((c=getc(f))!='\n' && c!=EOF); 
  852.   }
  853. }
  854.  
  855. int os_putc(int c, FILE *f) {
  856. int i;
  857.   if (f == stderr) {
  858.     i = wfputc(c, f);
  859.   } else {
  860.     i = fputc(c, f);
  861.   }
  862. #if 0
  863.   text_poll(0); /* Multitask a bit more... */
  864. #else
  865.   POLL ();
  866. #endif
  867.   return(i);
  868. }
  869.  
  870. void os_fputs(char *s, FILE *stream) {
  871.   if (stream == stderr) {
  872.     (void) wfputs(s, stream);
  873.   } else {
  874.     (void) fputs(s, stream);
  875.   }
  876. #if 0
  877.   text_poll(0); /* Multitask a bit more... */
  878. #else
  879.   POLL ();
  880. #endif
  881. }
  882.  
  883. void os_fput(char *s, FILE *stream) {
  884.   if (stream == stderr) {
  885.     (void) wfput(s, stream);
  886.   } else {
  887.     (void) fprintf(stream, "%s", s);
  888.   }
  889. #if 0
  890.   text_poll(0); /* Multitask a bit more... */
  891. #else
  892.   POLL ();
  893. #endif
  894. }
  895.  
  896. void os_fflush(FILE *f) {
  897.   if (f == stderr) {
  898.     wfflush(f);
  899.   } else {
  900.     fflush(f);
  901.   }
  902. #if 0
  903.   text_poll(0); /* Multitask a bit more... */
  904. #else
  905.   POLL ();
  906. #endif
  907. }
  908.  
  909. int os_feof(FILE *f) {
  910.   if (f == stdin) {
  911.     return(wfeof(f));
  912.   } else {
  913.     return(feof(f));
  914.   }
  915. }
  916.  
  917. void os_fclose(FILE *f) {
  918.   if (f == stderr || f == stdin) {
  919.     if (f) (void) wfclose(f);
  920.   } else {
  921.     if (f) (void) fclose(f);
  922.   }
  923. }
  924.  
  925. int os_getc(FILE *f) {
  926.   if (f == stdin) {
  927.     return(wgetc(f));
  928.   } else {
  929.     return(getc(f));
  930.   }
  931. }
  932.  
  933. int os_ungetc(int c, FILE *f) {
  934.   if (f == stdin) {
  935.     return(wungetc(c, f));
  936.   } else {
  937.     return(ungetc(c, f));
  938.   }
  939. }
  940.  
  941. void closemess(void) {
  942.   wfput("\nPress SPACE or click mouse to continue", stderr);
  943.   wfflush(stderr);
  944.   for (;;) {
  945.     int c = wgetc(stdin);
  946.     if (c == ' ') return;
  947.     if (c == 27) return;
  948.   }
  949. }
  950.  
  951. #endif
  952. #endif
  953.